package kibahed.university.effizientealgorithmen.fileinteractions;

import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JFileChooser;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import kibahed.university.effizientealgorithmen.interfaces.IEdge;
import kibahed.university.effizientealgorithmen.interfaces.IGraph;
import kibahed.university.effizientealgorithmen.interfaces.IVertex;
import kibahed.university.effizientealgorithmen.standardclasses.EdgeWithCosts;
import kibahed.university.effizientealgorithmen.standardclasses.Graph;
import kibahed.university.effizientealgorithmen.standardclasses.VertexDouble;
import kibahed.university.effizientealgorithmen.standardclasses.VertexSimple;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Fileloader {
	
	/**
	 * 
	 * @author Bernhard Kinast
	 * @author Daniel Heily
	 *
	 */
	
	public static IGraph loadGraphFromXMLFile(File file){
		
		IGraph graph = new Graph();
		graph.setTspName(file.getName());
		if(file!=null){
			System.out.println("Handling File"+file.getName());
			DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder dbBuilder=null;
			try {
				dbBuilder = dbFactory.newDocumentBuilder();
			} catch (ParserConfigurationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			Document doc=null;
			if(dbBuilder!=null){
				try {
					doc = dbBuilder.parse(file);
				} catch (SAXException | IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			if(doc!=null){
				NodeList root = doc.getElementsByTagName("graph");
				NodeList vertexes = root.item(0).getChildNodes();
				for(int i=0;i<vertexes.getLength();i++){
					IVertex vertex = new VertexSimple();
					Node vertexNode = vertexes.item(i);
					if(vertexNode.hasChildNodes()){
						for(int j=0;j<vertexNode.getChildNodes().getLength();j++){
							EdgeWithCosts edge = new EdgeWithCosts();
							Node edgeNode = vertexNode.getChildNodes().item(j);
							if(edgeNode.getNodeType()==Node.ELEMENT_NODE){
								Element edgeElement = (Element)edgeNode;
								edge.setCost(Double.parseDouble(edgeElement.getAttribute("cost")));
								edge.setEnd(Integer.parseInt(edgeElement.getTextContent()));
								vertex.add(edge);
							}
						}
						graph.addVertex(vertex);
					}
				}
			}
		}
		return graph;
	}
	
	public static File showOpenDialog(){
		
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException | InstantiationException
				| IllegalAccessException | UnsupportedLookAndFeelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		final File defaultLocation = new File(System.getProperty("user.dir"));
		final JFileChooser fileChooser = new JFileChooser(defaultLocation);
		fileChooser.showOpenDialog(null);
		final File choosenFile=fileChooser.getSelectedFile();
		return choosenFile;
	}

	public static IGraph loadGraphFromTSPFile(File file) {
		IGraph graph = null;
		
		try {
			TSPLIB_Parser parser = new TSPLIB_Parser(file.getPath());
			graph = new Graph();
			graph.setTspName(file.getName());
			double[][] matrix = parser.toDoubleMatrix();
			double[][] positions = parser.getVertices();
			Set<IEdge> edges = new HashSet<IEdge>();
			for(int i=0;i<matrix.length;i++){
				VertexDouble vertex = new VertexDouble();
				vertex.setPosition(positions[i][0], positions[i][1]);
				vertex.setID(i);
				for(int j=0;j<matrix[0].length;j++){
					if(i!=j){
						
						VertexDouble endVertex = new VertexDouble();
						endVertex.setID(j);
						endVertex.setPosition(positions[j][0], positions[j][1]);
						EdgeWithCosts edge = new EdgeWithCosts();
						edge.setCost(matrix[i][j]);
						edge.setStart(i);
						edge.setEnd(j);
						edge.setStartVertex(vertex);
						edge.setEndVertex(endVertex);
						vertex.add(edge);
						edges.add(edge);
					}
				}
				
				graph.addVertex(vertex);
			}
			
			System.out.println("number of edges = "+edges.size());
			graph.setEdges(edges);
			
			graph.setCostMatrix(parser.toDoubleMatrix());
			
			IEdge edge1 = new EdgeWithCosts();
			edge1.setStart(0);
			edge1.setEnd(1);
			IEdge edge2 = new EdgeWithCosts();
			edge2.setStart(1);
			edge2.setEnd(3);
			IEdge edge3 = new EdgeWithCosts();
			edge3.setStart(5);
			edge3.setEnd(8);
			IEdge edge4 = new EdgeWithCosts();
			edge4.setStart(9);
			edge4.setEnd(10);
			IEdge[] testEdges = new IEdge[]{edge1,edge2,edge3,edge4};
			//graph.setEdgeTour(testEdges);
			//graph.setNodeTour(new int[]{0,1,3,4,5,8});
			
		} catch (Exception | TSPParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return graph;
	}

}
